using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;
using MudWebApp.Helps;
using MudWebApp.Requests;

namespace MudWebApp.States;

public class CustomAuthenticationStateProvider : AuthenticationStateProvider
{
    private readonly ClaimsPrincipal _anonymous = new ClaimsPrincipal(new ClaimsIdentity());

    public override Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        if (string.IsNullOrEmpty(Constants.JwtToken))
        {
            return Task.FromResult(new AuthenticationState(_anonymous));
        }

        var userClaims = DecryptToken(Constants.JwtToken);
        if (string.IsNullOrEmpty(userClaims.Email))
        {
            return Task.FromResult(new AuthenticationState(_anonymous));
        }

        var claimPrincipal = SetClaimPrincipal(userClaims);
        return Task.FromResult(new AuthenticationState(claimPrincipal));
    }

    private static CustomUserClaims DecryptToken(string jwtToken)
    {
        if (string.IsNullOrEmpty(jwtToken)) return new CustomUserClaims();
        var handler = new JwtSecurityTokenHandler();
        var token = handler.ReadJwtToken(jwtToken);
        // 调试：查看所有 claims
        foreach (var claim in token.Claims)
        {
            Console.WriteLine($"Type: {claim.Type}, Value: {claim.Value}");
        }
        var name = token.Claims.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Name)?.Value;
        var email = token.Claims.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Email)?.Value;
        return new CustomUserClaims(name, email);
    }

    private static ClaimsPrincipal SetClaimPrincipal(CustomUserClaims userClaims)
    {
        if (userClaims.Email is null) return new ClaimsPrincipal();
        return new ClaimsPrincipal(new ClaimsIdentity([
            new Claim(ClaimTypes.Name, userClaims.Name!),
            new Claim(ClaimTypes.Email, userClaims.Email)
        ], "JwtAuth"));
    }

    public void UpdateAuthenticationState(string jwtToken)
    {
        var claimsPrincipal = new ClaimsPrincipal();
        if (!string.IsNullOrEmpty(jwtToken))
        {
            Constants.JwtToken = jwtToken;
            var userClaims = DecryptToken(jwtToken);
            claimsPrincipal = SetClaimPrincipal(userClaims);
        }
        else
        {
            Constants.JwtToken = string.Empty;
        }

        NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(claimsPrincipal)));
    }
}